import customReportService, { type PageListReq } from "@/api/services/tool/reportService";
import { TableToolbar } from "@/components/grid/TableToolbar";
import { t } from "@/locales/i18n";
import { Button, Card, Col, Form, Input, Modal, Row, Space, Tabs, Tooltip, Typography } from "antd";
import Table, { type ColumnsType } from "antd/es/table";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import type { CustomReport, CustomReportField, CustomReportParam, CustomReportVO } from "./entity";

import { QuestionCircleOutlined } from "@ant-design/icons";
import { sql } from "@codemirror/lang-sql";
import { githubLight } from "@uiw/codemirror-theme-github";
import CodeMirror from "@uiw/react-codemirror";
import type React from "react";

import DynamicQueryTable from "@/components/report/DynamicQueryTable";
import ReportFieldPage from "./reportField";
import ReportParamPage from "./reportParam";

const { Text } = Typography;

const sqlHelp = `
您可以键入“”作为一个参数，这里abc是参数的名称。例如：
select * from table where id = \${abc}。
select * from table where id like concat('%',\${abc},'%')。(mysql模糊查询)
select * from table where id like '%'||\${abc}||'%'。(oracle模糊查询)
select * from table where id like '%'+\${abc}+'%'。(sqlserver模糊查询)
注：参数只支持动态报表，popup暂不支持
`;

export default function CustomReportPage() {
	const [loading, setLoading] = useState(false);
	const [queryParams, setQueryParams] = useState<PageListReq>({
		reportName: undefined,
		reportCode: undefined,
		page: 1,
		pageSize: 10,
	});
	const [total, setTotal] = useState(0);
	const [list, setList] = useState<CustomReport[]>([]);
	const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
	const [tableSize, setTableSize] = useState<"large" | "middle" | "small">("middle");
	const [visible, setVisible] = useState(false);
	const [editingData, setEditingData] = useState<CustomReport | null>(null);
	const [form] = Form.useForm();
	const [isView, setIsView] = useState(true);
	const [activeTab, setActiveTab] = useState("1");

	const [fieldLoading, setFieldLoading] = useState(false);
	const [fieldList, setFieldList] = useState<CustomReportField[]>([]);

	const [paramLoading, setParamLoading] = useState(false);
	const [paramList, setParamList] = useState<CustomReportParam[]>([]);

	//展示报表编码
	const [showCode, setShowCode] = useState<string>("");
	//展示数据
	const [showVisiable, setShowVisiable] = useState(false);

	//sql脚本
	const [sqlCode, setSqlCode] = useState<string>("");

	const columns: ColumnsType<CustomReport> = [
		{
			title: "报表名称",
			key: "reportName",
			dataIndex: "reportName",
		},
		{
			title: "报表编码",
			key: "reportCode",
			dataIndex: "reportCode",
		},
		{
			title: "sql语句",
			key: "sql",
			dataIndex: "sqlScript",
			width: 450,
			ellipsis: true,
			render: (sqlScript) => (
				<Tooltip
					placement="topLeft"
					title={<div style={{ maxWidth: 600, whiteSpace: "pre-wrap" }}>{sqlScript}</div>}
					overlayStyle={{ maxWidth: 600 }}
				>
					<Text ellipsis style={{ width: 430 }}>
						{sqlScript}
					</Text>
				</Tooltip>
			),
		},
		{
			title: "描述",
			key: "description",
			dataIndex: "description",
		},
		{
			title: "操作",
			fixed: "right",
			key: "operation",
			align: "center",
			width: 100,
			render: (_, record) => (
				<Space>
					<Button type="link" onClick={() => handleView(record)}>
						{t("common.view")}
					</Button>
					<Button type="link" onClick={() => handleEdit(record)}>
						{t("common.edit")}
					</Button>
					<Button type="link" onClick={() => handleShow(record)}>
						展示数据
					</Button>
				</Space>
			),
		},
	];

	const [selectedValues, setSelectedValues] = useState<string[]>(() =>
		columns.filter((col) => col.key !== "operation").map((col) => String(col.key!)),
	);

	const filteredColumns = useMemo(() => {
		return [...columns.filter((col) => selectedValues.includes(String(col.key)) || col.key === "operation")].sort(
			(a, b) => {
				const originalIndex = columns.findIndex((c) => c.key === a.key);
				const targetIndex = columns.findIndex((c) => c.key === b.key);
				return originalIndex - targetIndex;
			},
		);
	}, [selectedValues]);

	//加载表格数据
	const fetchPageList = () => {
		setLoading(true);
		customReportService
			.pageList(queryParams)
			.then((res) => {
				setList(res.records);
				setTotal(res.total);
			})
			.catch((error) => {
				console.log(error);
				toast.error("获取数据失败！", error);
			})
			.finally(() => {
				setLoading(false);
			});
	};

	useEffect(() => {
		fetchPageList();
	}, [queryParams]);

	//选择其他页
	const handlePageChange = (newPage: number, newPageSize: number) => {
		setQueryParams((prev) => ({
			...prev,
			page: newPage,
			pageSize: newPageSize,
		}));
	};

	//触发编辑按钮
	const handleEdit = (customReport: CustomReport) => {
		setEditingData(customReport);
		if (customReport.id) {
			setFormValue(customReport.id);
		}
		setVisible(true);
		setIsView(false);
	};

	//触发视图按钮
	const handleView = (customReport: CustomReport) => {
		setEditingData(customReport);
		if (customReport.id) {
			setFormValue(customReport.id);
		}
		setIsView(true);
		setVisible(true);
	};

	//打开展示数据
	const handleShow = (customReport: CustomReport) => {
		setShowCode(customReport.reportCode);
		setShowVisiable(true);
	};

	const setFormValue = async (reportId: React.Key) => {
		await customReportService.getInfo(reportId).then((res) => {
			form.setFieldsValue(res);
			if (res.sqlScript) {
				setSqlCode(res.sqlScript);
			}
			if (res.customReportFields) {
				setFieldList(res.customReportFields);
			}
			if (res.customReportParams) {
				setParamList(res.customReportParams);
			}
		});
	};

	//提交表单数据
	const handleSubmit = async (values) => {
		setLoading(true);
		console.log("表单数据", values);
		console.log(form.getFieldsValue());
		const data: CustomReportVO = {
			...values,
			id: editingData?.id,
			sqlScript: sqlCode,
			customReportFields: fieldList,
			customReportParams: paramList,
		};

		await customReportService
			.add(data)
			.then((res) => {
				toast.success("保存成功");
			})
			.catch((error) => {
				toast.error(`${error.message}`);
			})
			.finally(() => {
				setVisible(false);
				setEditingData(null);
				form.resetFields();
				fetchPageList();
				setLoading(false);
			});
	};

	const handleModalClose = () => {
		setVisible(false);
		setEditingData(null);
		form.resetFields();
	};

	const handleAdd = () => {
		setEditingData(null);
		form.resetFields();
		// setSqlCode("");
		setFieldList([]);
		setParamList([]);
		setVisible(true);
		setIsView(false);
	};

	const handleDelete = async () => {
		try {
			setLoading(true);
			await customReportService.remove(selectedRowKeys);
			toast.success("删除自定义报成功");
			setSelectedRowKeys([]);
			fetchPageList();
		} catch (error) {
			toast.error(`删除失败: ${error.message}`);
		} finally {
			setLoading(false);
		}
	};

	//解析sql语句
	const handleParseSql = async () => {
		setFieldLoading(true);

		const data: CustomReportVO = {
			reportCode: form.getFieldValue("reportCode"),
			reportName: form.getFieldValue("reportName"),
			sqlScript: sqlCode,
			customReportFields: fieldList,
			customReportParams: paramList,
		};

		await customReportService
			.parseSql(data)
			.then((res) => {
				setFieldList(res);
				setActiveTab("1");
			})
			.catch((error) => {
				toast.error(error.message);
			})
			.finally(() => {
				setFieldLoading(false);
			});
	};

	return (
		<>
			{/* 查询条件 */}
			<Card className="mb-4">
				<Form
					layout="inline"
					onFinish={(values) => {
						setQueryParams((prev) => ({
							...prev,
							...values,
							page: 1,
						}));
					}}
				>
					<Form.Item name="reportName" label="报表名称">
						<Input placeholder="请输入报表名称" allowClear />
					</Form.Item>
					<Form.Item name="reportCode" label="报表编码">
						<Input placeholder="请输入报表编码" allowClear />
					</Form.Item>
					<Form.Item>
						<Button type="primary" htmlType="submit">
							查询
						</Button>
						<Button
							className="ml-2"
							onClick={() => {
								setQueryParams({ page: 1, pageSize: 10 });
							}}
						>
							重置
						</Button>
					</Form.Item>
				</Form>
			</Card>
			<div className="h-4" />
			{/* 表格数据 */}
			<Card>
				<div className="flex justify-between mb-4">
					<div className="flex gap-2">
						<Button type="primary" onClick={handleAdd}>
							新增
						</Button>
						<Button danger disabled={selectedRowKeys.length === 0} onClick={handleDelete}>
							删除
						</Button>
					</div>
					<TableToolbar
						onRefresh={() => setQueryParams((prev) => ({ ...prev }))}
						onSizeChange={setTableSize}
						columns={columns}
						selectedValues={selectedValues}
						onColumnChange={setSelectedValues}
					/>
				</div>
				<Table
					rowKey="id"
					size={tableSize}
					scroll={{ x: "max-content" }}
					loading={loading}
					pagination={{
						total,
						current: queryParams.page,
						pageSize: queryParams.pageSize,
						onChange: handlePageChange,
					}}
					columns={filteredColumns}
					dataSource={list}
					rowSelection={{
						type: "checkbox",
						selectedRowKeys: selectedRowKeys,
						onChange: (selectedKeys) => {
							setSelectedRowKeys(selectedKeys as string[]);
						},
					}}
				/>
			</Card>
			{/* 编辑页面 */}
			<Modal
				title={editingData ? "编辑自定义报" : "新增自定义报"}
				open={visible}
				width="100%"
				style={{ top: 0, maxWidth: "98vw", padding: 10 }}
				styles={{
					body: { height: "calc(100vh - 200px)", overflow: "auto", padding: "10px 24px" },
					content: { maxWidth: "100vw", overflow: "hidden" },
					header: { padding: "16px 24px" },
					footer: { padding: "10px 24px" },
				}}
				onCancel={handleModalClose}
				footer={
					<div className="flex justify-end gap-2">
						<Button onClick={handleModalClose}>取消</Button>
						{!isView && (
							<Button type="primary" onClick={() => form.submit()}>
								确定
							</Button>
						)}
					</div>
				}
			>
				<Form form={form} onFinish={handleSubmit} disabled={isView}>
					<Row gutter={16}>
						<Col span={12}>
							<Form.Item name="reportName" label="报表名称" rules={[{ required: true, message: "请输入报表名称!" }]}>
								<Input placeholder="请输入报表名称" />
							</Form.Item>
						</Col>
						<Col span={12}>
							<Form.Item name="reportCode" label="报表编码" rules={[{ required: true, message: "请输入报表编码!" }]}>
								<Input placeholder="请输入报表编码" />
							</Form.Item>
						</Col>
					</Row>
					<Row gutter={16}>
						<Col span={21}>
							<Form.Item name="sqlScript" label="报表SQL" required>
								<CodeMirror
									value={sqlCode}
									height="180px"
									extensions={[sql()]}
									theme={githubLight}
									style={{
										border: "1px solid #d9d9d9",
										borderRadius: "4px",
									}}
									onChange={(value) => setSqlCode(value)}
								/>
							</Form.Item>
						</Col>
						<Col span={3}>
							<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: "right", marginTop: 12 }}>
								<Space>
									<Tooltip
										placement="left"
										title={<div style={{ maxWidth: 500, whiteSpace: "pre-wrap" }}>{sqlHelp}</div>}
										overlayStyle={{ maxWidth: 500 }}
									>
										<QuestionCircleOutlined style={{ fontSize: "16px" }} />
									</Tooltip>
									<Button type="primary" onClick={handleParseSql}>
										SQL解析
									</Button>
								</Space>
							</Form.Item>
						</Col>
					</Row>
				</Form>

				{/* 子表信息 */}
				<Tabs
					activeKey={activeTab}
					onChange={setActiveTab}
					items={[
						{
							key: "1",
							label: "报表字段",
							children: <ReportFieldPage fieldList={fieldList} setFieldList={setFieldList} loading={fieldLoading} />,
						},
						{
							key: "2",
							label: "报表参数",
							children: <ReportParamPage paramList={paramList} setParamList={setParamList} loading={paramLoading} />,
						},
					]}
				/>
			</Modal>
			{/* 数据展示 */}
			<Modal
				title="报表数据"
				open={showVisiable}
				width="100%"
				style={{ top: 0, maxWidth: "98vw", padding: 10 }}
				styles={{
					body: { height: "calc(100vh - 200px)", overflow: "auto", padding: "10px 24px" },
					content: { maxWidth: "100vw", overflow: "hidden" },
					header: { padding: "16px 24px" },
					footer: { padding: "10px 24px" },
				}}
				onCancel={() => setShowVisiable(false)}
			>
				<DynamicQueryTable reportCode={showCode} />
			</Modal>
		</>
	);
}
